package com.perfma.xtest.tool;


import com.perfma.paas.common.openapi.DefaultSdkClient;
import com.perfma.paas.common.openapi.http.*;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * @author: junhui.si
 * @date: 2023-02-07 15:38
 **/
public class V4OpenApiSdk {
    private static final String BOUNDARY = "===" + System.currentTimeMillis() + "==";
    public static void main(String[] args) {

        String filePath = "/Users/sijunhui/Downloads/log/zy.zip";
        String urlString = "http://10.10.30.103:8081/api/xsea/open/zy/scene/run";
        String sceneId = "123";

        //【必须】初始化 SDK 客户端
        DefaultSdkClient client = DefaultSdkClient.getClient("http://10.10.30.103:8081", "382d2c2ae91f4c3a87aab1857ab882ab", "7007fcc10e914467bcdbcfbe7699be1a", "weixi");

        //【可选】设置 Client 级别超时时间
        client.setConnectionTimeoutMillis(10000);// 连接超时时间，默认值 3000ms
        client.setReadTimeoutMillis(30000);// 执行超时时间，默认值 10000ms

        //【可选】设置 HTTP 客户端实现，默认是 JDK 实现，可以基于 ApacheHttpClient 等类库自行扩展实现
        client.setHttpClient(new HttpClient() {
            @Override
            public RestResponse syncInvoke(HttpRequest httpRequest) throws IOException {
                try {
                    URL url = new URL(urlString);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    connection.setDoOutput(true);
                    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

                    DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

                    // Write the binary data of the file
                    writePart(outputStream, "file", new File(filePath));

                    // Write the sceneId as a text part
                    writePart(outputStream, "sceneId", "123");

                    // End of multipart form data
                    outputStream.writeBytes("--" + BOUNDARY + "--\r\n");
                    outputStream.flush();
                    outputStream.close();

                    int responseCode = connection.getResponseCode();
                    System.out.println("Response Code : " + responseCode);

                    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String inputLine;
                    StringBuffer response = new StringBuffer();

                    while ((inputLine = in.readLine()) != null) {
                        response.append(inputLine);
                    }
                    in.close();

                    // Print result
                    System.out.println(response.toString());

//                    InputStream content = connection.getInputStream();
//                    RestResponse response = getResponse(connection, content);
                    return null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            public void download(HttpRequest httpRequest) throws IOException {

            }
        });

        //【必须】初始化请求
        // 构造入参是 uriPattern，可以包含参数变量，不包含?之后的部分
        RestRequest request = new RestRequest("/api/xsea/open/zy/scene/run");

        //【可选】设置请求方法，默认是 GET
        request.setMethod(RequestMethod.POST);
        //【可选】设置 ContentType，默认是 application/json
        request.setContentType(ContentType.RAW);
        //【可选】设置编码字符集，默认是 UTF-8
        request.setCharset("UTF-8");

        //【可选】设置 Request 级别超时时间，如果设置了，优先级高于 Client 级别
        request.setConnectionTimeoutMillis(50000);
        request.setReadTimeoutMillis(10000);
//        request.setFile(new File("/Users/sijunhui/Downloads/log/zy.zip"));

        //【可选】设置入参，以下几种参数并不都是必须的，通常也不会同时使用，这里只是做完整示例
//        request.putQueryParameters("zySceneId", "123");// 设置查询参数（地址栏?之后的部分），不需要做 URLEncode
//        // 设置请求体，按指定的编码序列化字符串；也可以直接调用 setRequestBody 设置二进制值
        request.setStringBody("{\n" +
                "    \"execTrendType\": \"USER\",\n" +
                "    \"endTime\":1675760101000,\n" +
                "    \"execId\":146830918331400192,\n" +
                "    \"appClusterIds\": [15100275897401344],\n" +
                "    \"transactionNameList\":[\"4-付款事务\"]\n" +
                "}");

        // 执行请求，得到结果
        RestResponse restResponse = client.execute(request);

        // 响应头
//        System.out.println(restResponse.getHeaders());
        // 响应体，序列化成字符串
        System.out.println(restResponse.getData());

    }
    private static void writePart(DataOutputStream out, String name, File file) throws IOException {
        String headerTemplate = "Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n"
                + "Content-Type: %s\r\n\r\n";

        String header = String.format(headerTemplate, name, file.getName(), URLConnection.guessContentTypeFromName(file.getName()));
        out.writeBytes("--" + BOUNDARY + "\r\n");
        out.writeBytes(header);
        out.write(("\r\n").getBytes(StandardCharsets.UTF_8));

        try (FileInputStream fis = new FileInputStream(file)) {
            byte[] buffer = new byte[4096];
            int count;
            while ((count = fis.read(buffer)) != -1) {
                out.write(buffer, 0, count);
            }
        }
        out.write(("\r\n").getBytes(StandardCharsets.UTF_8));
    }

    private static void writePart(DataOutputStream out, String name, String value) throws IOException {
        String headerTemplate = "Content-Disposition: form-data; name=\"%s\"\r\n\r\n";
        out.writeBytes("--" + BOUNDARY + "\r\n");
        out.writeBytes(String.format(headerTemplate, name));
        out.write(value.getBytes(StandardCharsets.UTF_8));
        out.write(("\r\n").getBytes(StandardCharsets.UTF_8));
    }


    private static RestResponse getResponse(HttpURLConnection httpConn, InputStream content)
            throws IOException {
        RestResponse response = new RestResponse();
        byte[] buff = readContent(content);
        //response.setHttpStatus(httpConn.getResponseCode());
        Map<String, List<String>> headers = httpConn.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
            String key = entry.getKey();
            if (null == key) {
                continue;
            }
            List<String> values = entry.getValue();
            StringBuilder builder = new StringBuilder(values.get(0));
            for (int i = 1; i < values.size(); i++) {
                builder.append(",");
                builder.append(values.get(i));
            }
            response.putHeader(key, builder.toString());
        }
        String charset = "UTF-8";
        String type = response.getHeader("Content-Type");
        if (null != buff && null != type) {
            String[] split = type.split(";");
            if (split.length > 1 && split[1].contains("=")) {
                String[] codings = split[1].split("=");
                if (codings.length > 1) {
                    charset = codings[1];
                }
            }
        }
        String stringContent = "";
        if (buff != null) {
            stringContent = new String(buff, charset);
        }
        response.setResponseCode(httpConn.getResponseCode());
        response.setData(stringContent);
        return response;
    }

    private static byte[] readContent(InputStream content) throws IOException {
        if (content == null) {
            return null;
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buff = new byte[1024];
        while (true) {
            final int read = content.read(buff);
            if (read == -1) {
                break;
            }
            outputStream.write(buff, 0, read);
        }
        return outputStream.toByteArray();
    }
}
